# Python中的函数

# 基本定义格式


# 函数开始需要有一个def 并且函数列表后面需要接上冒号
# 返回值不需要写
# def add(x, y):
#     return x + y
#
# x = 10
# y = 20
# print(add(x, y))

# Python中的函数只要求参数个数匹配 而由于动态类型不要求类型匹配 但是要保证传过去的参数在函数体内能够
# 被正确的运算

# def add(x, y, z):
#     print(x + y + z)
#
# a = 'hello '
# b = 'world!'
# c = 10
# d = 'xixi'
# add(a, b, d)

# 函数的返返回值可以有多个 返回值使用逗号隔开即可
# 可以只接收多个返回值中其中一部分的值 这个时候用'_'接收忽略的返回值即可

# def func(x, y, z):
#     return x + y, x + z, y + z
#
# a = 10
# b = 20
# c = 30
# # 先看看接收全部返回值的情况
# r1, r2, r3 = func(a, b, c)
# print(r1, r2, r3)
# # 不想接收x + y这个值 写法 但是还是可以打印出来的 因为下划线是一个合法的变量名
# _, r3, r4 = func(a, b, c)
# print(_, r3, r4)

# 函数变量的作用域只是在当前函数代码块 也就是说在函数体之外的作用域看不到这个变量
# 条件、循环、选择语句中定义的变量的作用域是全局的
# 使用global关键字可以将函数体内定义的变量的作用域改为全局的

# x = 20
#
# def func():
#     global x
#     x = 10
#     print(f'函数内部的x = {x}')
#
# func()
# print(f'函数外部的x = {x}') #可以看到函数内部将x改变之后外面的x的值也变为相应修改的值
#
# for i in range(1, 11):
#     print(i)
# print(i)

# pycharm中的调试
# 先设置断点 点击左侧行号 让代码走到这个断点处
# 之后右键调试 之后step into (f7)逐行调试
# def test():
#     print('执行函数内部代码')
#     print('执行函数内部代码')
#     print('执行函数内部代码')
#
# print('1111')
# test()
# print('2222')
# test()
# print('3333')
# test()

# 链式调用 : 一个函数的返回值可以作为另一个函数的参数
# 嵌套调用 : 一个函数中可以调用其他的函数

# 函数栈帧 : 每一个函数都在内存上开辟了一块空间 这块空间存着对应函数的变量 这就是函数栈帧
# 函数调完之后栈帧摧毁
# 在pycharm中调式的时候可以在左下角看到建立的函数栈帧

#def a():
#     a = 100
#     print('a')
# def b():
#     b = 200
#     print('b')
#     a()
# def c():
#     c = 300
#     print('c')
#     b()
# def d():
#     d = 400
#     print('d')
#     c()
#
# d()

# 函数可以设置缺省值

# def test(x, y, default = False):
#     if default:
#         print(f'x = {x}, y = {y}')
#
# x = 10
# y = 20
# test(x, y)
# test(x, y, True)

# python中的传参可以使用关键字参数 这种传参的好处就是可以无视传参顺序 指定传的参数

def test(x, y, z):
    print(f'x = {x}, y = {y}, z = {z}')

test(y = 100, x = 200, z = 0)
